package cn.mw.cmdb.util;

import cn.hutool.core.bean.BeanUtil;
import cn.mw.cmdb.entity.PropertyInfo;
import cn.mw.cmdb.view.TreeViewObjectV1;
import cn.mw.components.mongodb.anno.CMDBProperty;
import cn.mw.components.mongodb.config.MongoConstant;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.entity.cmdb.TableHeaderItem;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public class CMDBTableTool {

    /**
     * 生成表头
     *
     * @param fields 字段名列表
     * @param aliasMap 字段别名列表
     * @param clazz 从类中取出Schema信息作为字段表中文名
     * @return 表头列表信息
     */
    public static List<TableHeaderItem> getTableHeaderFromSchema(List<String> fields , Map<String ,String> aliasMap, Class clazz) throws Exception{
        if(null == fields){
            return null;
        }

        List<TableHeaderItem> tableHeaderItems = new ArrayList<>();
        for(String fieldName: fields){
            TableHeaderItem tableHeaderItem = new TableHeaderItem();

            if(null != aliasMap){
                String alias = aliasMap.get(fieldName);
                if(StringUtils.hasText(alias)){
                    tableHeaderItem.setField(alias);
                }else{
                    tableHeaderItem.setField(fieldName);
                }
            }else{
                tableHeaderItem.setField(fieldName);
            }


            Field field = clazz.getDeclaredField(fieldName);
            Schema schema = field.getAnnotation(Schema.class);
            if(null != schema){
                tableHeaderItem.setHeaderName(schema.description());
            }

            CMDBProperty cmdbProperty = field.getAnnotation(CMDBProperty.class);
            if(null != cmdbProperty){
                tableHeaderItem.setPropertyTypeId(cmdbProperty.searchType());
            }
            tableHeaderItems.add(tableHeaderItem);
        }

        return tableHeaderItems;
    }

    public static List<TableHeaderItem> getTableHeaderFromPropertyInfo(List<PropertyInfo> propertyInfos) throws Exception{
        List<TableHeaderItem> tableHeaderItems = null;
        if(null == propertyInfos){
            return null;
        }

        tableHeaderItems = new ArrayList<>();
        for(PropertyInfo propertyInfo: propertyInfos){
            TableHeaderItem tableHeaderItem = new TableHeaderItem();
            tableHeaderItem.setField(propertyInfo.getId());
            String name = StringUtils.hasText(propertyInfo.getDesc())?propertyInfo.getDesc():propertyInfo.getName();
            tableHeaderItem.setHeaderName(name);
            tableHeaderItem.setPropertyTypeId(propertyInfo.getPropertyType().id);
            tableHeaderItems.add(tableHeaderItem);
        }

        return  tableHeaderItems;
    }

    public static List<Map> formateTreeTableHeaderV1(List<TableHeaderItem> tableHeaderItems ,Set<String> excludeFields){
        List<Map> list = new ArrayList<>();
        for(TableHeaderItem tableHeaderItem : tableHeaderItems){
            if(null != excludeFields && excludeFields.contains(tableHeaderItem.getField().toLowerCase())){
                continue;
            }

            Map data = BeanUtil.beanToMap(tableHeaderItem);
            data.put("openThisColWithGroup" ,true);
            list.add(data);
        }
        return list;
    }

    public static List<Map> formateTableHeaderV1(List<TableHeaderItem> tableHeaderItems ,Set<String> excludeFields){
        List<Map> list = new ArrayList<>();
        for(TableHeaderItem tableHeaderItem : tableHeaderItems){
            if(null != excludeFields && excludeFields.contains(tableHeaderItem.getField().toLowerCase())){
                continue;
            }
            Map data = BeanUtil.beanToMap(tableHeaderItem);
            list.add(data);
        }
        return list;
    }

    public static List<TreeView> formateTreeTableDetailV1(List<TreeView> list){
        Map<Object, TreeViewObjectV1> map = new HashMap<>();
        List<TreeView> ret = new ArrayList<>();
        for (TreeView treeView : list) {
            TreeViewObjectV1 treeViewObject = new TreeViewObjectV1();
            treeViewObject.setId(treeView.getId().toString());

            treeViewObject.setItemName(treeView.getItemName());
            treeViewObject.setType(treeView.getType());
            treeViewObject.setChildStatus(treeView.getChildStatus());
            treeViewObject.setViewType(treeView.getViewType());
            map.put(treeView.getId().toString(), treeViewObject);
            //多个parentId的情况,需要分解
            if (null == treeView.getParentId()) {
                ret.add(treeViewObject);
            } else {
                treeViewObject.setParentId(treeView.getParentId());
            }
        }
        List<TreeViewObjectV1> lists = map.values().stream().toList();
        List<TreeViewObjectV1> sortList = lists.stream().sorted(Comparator.comparing(TreeView::getItemName)).collect(Collectors.toList());

        for (TreeViewObjectV1 treeView : sortList) {
            if (null != treeView.getParentId()) {
                TreeViewObjectV1 treeViewObject = map.get(treeView.getParentId().toString());
                if (null != treeViewObject) {
                    treeViewObject.addTreeView(treeView);
                }
            }
        }


        return ret;
    }

    public static String getMongoFieldPath(String[] fields){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(fields[0]);
        if(fields.length > 1){
            for(int i= 1;i < fields.length;i++){
                stringBuffer.append(MongoConstant.FieldSep).append(fields[i]);
            }
        }
        return stringBuffer.toString();
    }
}
